package cn.harry.cabinet.view.fragments

import android.content.Context
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.inputmethod.InputMethodManager
import android.widget.Button
import android.widget.EditText
import android.widget.TextView
import android.widget.Toast
import androidx.lifecycle.lifecycleScope
import cn.harry.cabinet.R
import cn.harry.cabinet.model.entity.Configuration
import cn.harry.cabinet.repository.ConfigurationRepository
import cn.harry.cabinet.theme.components.ThemePreviewComponent
import cn.harry.cabinet.theme.manager.ButtonThemeManager
import cn.harry.cabinet.theme.manager.ThemeManager
import cn.harry.cabinet.utils.AppConfigKeys
import cn.harry.cabinet.utils.logConfigChange
import cn.harry.cabinet.utils.logThemeChange
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

class HomeConfigFragment : BaseFragment() {

    private lateinit var titleEditText: EditText
    private lateinit var returnLabelEditText: EditText
    private lateinit var takeLabelEditText: EditText
    private lateinit var deviceNumberEditText: EditText
    private lateinit var saveButton: Button
    
    // 主题相关控件
    private lateinit var chinaRedPreview: ThemePreviewComponent
    private lateinit var vibrantOrangePreview: ThemePreviewComponent
    private lateinit var techBluePreview: ThemePreviewComponent
    private lateinit var currentThemeText: TextView

    private lateinit var repository: ConfigurationRepository

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.fragment_home_config, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        repository = ConfigurationRepository(requireActivity().application)

        titleEditText = view.findViewById(R.id.et_home_title)
        returnLabelEditText = view.findViewById(R.id.et_home_return_label)
        takeLabelEditText = view.findViewById(R.id.et_home_take_label)
        deviceNumberEditText = view.findViewById(R.id.et_home_device_number)
        saveButton = view.findViewById(R.id.btn_save_home_config)
        
        // 初始化主题相关控件
        chinaRedPreview = view.findViewById(R.id.theme_preview_china_red)
        vibrantOrangePreview = view.findViewById(R.id.theme_preview_vibrant_orange)
        techBluePreview = view.findViewById(R.id.theme_preview_tech_blue)
        currentThemeText = view.findViewById(R.id.tv_current_theme)
        
        // 设置主题预览
        setupThemePreviews()

        saveButton.setOnClickListener {
            saveConfigs()
        }
        
        // 设置主题选择点击事件
        setupThemeSelectors()

        loadConfigs()
        updateCurrentThemeDisplay()
        
        // 防止页面打开时自动弹出键盘
        hideKeyboardOnLoad()
    }
    
    /**
     * 重写主题应用方法，跳过主题预览组件中的按钮
     * 主题预览组件需要保持各自主题的固有颜色
     */
    override fun applyThemeToFragment() {
        view?.let { fragmentView ->
            try {
                val currentTheme = ThemeManager.getCurrentTheme(requireContext())
                
                // 只应用按钮主题，不应用DynamicThemeUpdater（避免影响主题预览组件）
                ButtonThemeManager.updateAllButtonsInView(fragmentView, currentTheme, requireContext())
                
            } catch (e: Exception) {
                android.util.Log.w("HomeConfigFragment", 
                    "Failed to apply theme: ${e.message}")
            }
        }
    }
    
    /**
     * 页面加载时隐藏键盘，防止自动弹出
     */
    private fun hideKeyboardOnLoad() {
        view?.post {
            // 清除所有EditText的焦点
            titleEditText.clearFocus()
            returnLabelEditText.clearFocus()
            takeLabelEditText.clearFocus()
            deviceNumberEditText.clearFocus()
            
            // 确保键盘隐藏
            val imm = requireContext().getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
            imm.hideSoftInputFromWindow(view?.windowToken, 0)
            
            // 让父容器获取焦点，防止EditText自动获得焦点
            view?.requestFocus()
            
            // 设置EditText点击时才启用触摸焦点
            setupEditTextFocusHandling()
        }
    }
    
    /**
     * 设置EditText的焦点处理，只有在用户主动点击时才获取焦点
     */
    private fun setupEditTextFocusHandling() {
        val editTexts = listOf(titleEditText, returnLabelEditText, takeLabelEditText, deviceNumberEditText)
        
        editTexts.forEach { editText ->
            editText.setOnClickListener {
                // 用户点击时启用触摸焦点并获取焦点
                editText.isFocusableInTouchMode = true
                editText.requestFocus()
                
                // 显示键盘
                val imm = requireContext().getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
                imm.showSoftInput(editText, InputMethodManager.SHOW_IMPLICIT)
            }
            
            // 失去焦点时禁用触摸焦点
            editText.setOnFocusChangeListener { _, hasFocus ->
                if (!hasFocus) {
                    editText.isFocusableInTouchMode = false
                }
            }
        }
    }

    private fun loadConfigs() {
        viewLifecycleOwner.lifecycleScope.launch {
            val list = withContext(Dispatchers.IO) { repository.getByType(AppConfigKeys.TYPE_HOME) }
            val map = list.associateBy { it.key }
            // 资源默认值
            val defaultTitle = getString(R.string.app_name)
            val defaultReturn = getString(R.string.return_item)
            val defaultTake = getString(R.string.take_item)
            val defaultDevice = getString(R.string.default_device_number)

            val title = map[AppConfigKeys.KEY_HOME_TITLE]?.value ?: defaultTitle
            val labelReturn = map[AppConfigKeys.KEY_HOME_LABEL_RETURN]?.value ?: defaultReturn
            val labelTake = map[AppConfigKeys.KEY_HOME_LABEL_TAKE]?.value ?: defaultTake
            val deviceNo = map[AppConfigKeys.KEY_HOME_DEVICE_NUMBER]?.value ?: defaultDevice

            titleEditText.setText(title)
            returnLabelEditText.setText(labelReturn)
            takeLabelEditText.setText(labelTake)
            deviceNumberEditText.setText(deviceNo)
        }
    }

    private fun saveConfigs() {
        val title = titleEditText.text.toString()
        val labelReturn = returnLabelEditText.text.toString()
        val labelTake = takeLabelEditText.text.toString()
        val deviceNo = deviceNumberEditText.text.toString()

        viewLifecycleOwner.lifecycleScope.launch {
            try {
                // 获取修改前的值
                val oldValues = withContext(Dispatchers.IO) {
                    val list = repository.getByType(AppConfigKeys.TYPE_HOME)
                    list.associateBy { it.key }.mapValues { it.value.value }
                }
                
                val oldTitle = oldValues[AppConfigKeys.KEY_HOME_TITLE] ?: getString(R.string.app_name)
                val oldReturn = oldValues[AppConfigKeys.KEY_HOME_LABEL_RETURN] ?: getString(R.string.return_item)
                val oldTake = oldValues[AppConfigKeys.KEY_HOME_LABEL_TAKE] ?: getString(R.string.take_item)
                val oldDevice = oldValues[AppConfigKeys.KEY_HOME_DEVICE_NUMBER] ?: getString(R.string.default_device_number)
                
                // 保存新值
                withContext(Dispatchers.IO) {
                    upsertConfig(AppConfigKeys.KEY_HOME_TITLE, title)
                    upsertConfig(AppConfigKeys.KEY_HOME_LABEL_RETURN, labelReturn)
                    upsertConfig(AppConfigKeys.KEY_HOME_LABEL_TAKE, labelTake)
                    upsertConfig(AppConfigKeys.KEY_HOME_DEVICE_NUMBER, deviceNo)
                }
                
                // 构建修改详情
                val changes = mutableListOf<String>()
                if (oldTitle != title) changes.add("标题: $oldTitle → $title")
                if (oldReturn != labelReturn) changes.add("归还标签: $oldReturn → $labelReturn")
                if (oldTake != labelTake) changes.add("取出标签: $oldTake → $labelTake")
                if (oldDevice != deviceNo) changes.add("设备编号: $oldDevice → $deviceNo")
                
                // 记录配置修改日志（带详细信息）
                if (changes.isNotEmpty()) {
                    val detailData = changes.joinToString("\n")
                    requireContext().logConfigChange(
                        scope = viewLifecycleOwner.lifecycleScope,
                        subType = "HOME_CONFIG",
                        description = "修改首页配置: ${changes.joinToString(", ")}",
                        oldValue = oldValues.toString(),
                        newValue = detailData
                    )
                }
                
                // 读取一次确认持久化成功，并刷新表单
                loadConfigs()
                Toast.makeText(requireContext(), "保存成功", Toast.LENGTH_SHORT).show()
            } catch (e: Exception) {
                Toast.makeText(requireContext(), "保存失败: ${e.message}", Toast.LENGTH_LONG).show()
            }
        }
    }

    private suspend fun upsertConfig(key: String, value: String) {
        val existing = repository.getByTypeAndKey(AppConfigKeys.TYPE_HOME, key)
        if (existing == null) {
            repository.create(
                Configuration(
                    type = AppConfigKeys.TYPE_HOME,
                    key = key,
                    value = value
                )
            )
        } else {
            repository.update(existing.copy(value = value, updateTime = java.util.Date()))
        }
    }
    
    /**
     * 设置主题预览组件
     */
    private fun setupThemePreviews() {
        // 设置每个主题预览的内容和点击事件
        chinaRedPreview.setTheme(ThemeManager.Theme.CHINA_RED)
        chinaRedPreview.setOnThemeClickListener(ThemeManager.Theme.CHINA_RED) { theme ->
            selectTheme(theme)
        }
        
        vibrantOrangePreview.setTheme(ThemeManager.Theme.VIBRANT_ORANGE)
        vibrantOrangePreview.setOnThemeClickListener(ThemeManager.Theme.VIBRANT_ORANGE) { theme ->
            selectTheme(theme)
        }
        
        techBluePreview.setTheme(ThemeManager.Theme.TECH_BLUE)
        techBluePreview.setOnThemeClickListener(ThemeManager.Theme.TECH_BLUE) { theme ->
            selectTheme(theme)
        }
        
        // 延迟一点确保所有组件都已经完全初始化，然后强制刷新图标颜色
        view?.post {
            chinaRedPreview.setTheme(ThemeManager.Theme.CHINA_RED)
            vibrantOrangePreview.setTheme(ThemeManager.Theme.VIBRANT_ORANGE)
            techBluePreview.setTheme(ThemeManager.Theme.TECH_BLUE)
        }
    }
    
    /**
     * 设置主题选择器点击事件 (已弃用，由setupThemePreviews替代)
     */
    private fun setupThemeSelectors() {
        // 这个方法已被setupThemePreviews替代
        // 保留是为了向后兼容，实际不会被调用
    }
    
    /**
     * 选择主题并应用
     */
    private fun selectTheme(theme: ThemeManager.Theme) {
        val oldTheme = ThemeManager.getCurrentTheme(requireContext())
        
        ThemeManager.setTheme(requireContext(), theme)
        updateCurrentThemeDisplay()
        
        // 应用主题到当前Activity
        ThemeManager.applyTheme(requireActivity(), theme)
        
        // 确保SystemConfigActivity的工具栏图标为白色（延迟执行确保主题完全应用）
        view?.post {
            (requireActivity() as? cn.harry.cabinet.view.SystemConfigActivity)?.forceUpdateToolbarIconColor()
        }
        
        // 动态更新当前Fragment的视图（但不处理按钮，避免冲突）
        view?.let { fragmentView ->
            // 只使用ButtonThemeManager来处理按钮，避免与DynamicThemeUpdater冲突
            cn.harry.cabinet.theme.manager.ButtonThemeManager.updateAllButtonsInView(
                fragmentView, theme, requireContext()
            )
            
            // 对于非按钮元素，使用DynamicThemeUpdater
            // 注意：这里可能需要一个不处理按钮的版本，但先尝试这种方式
        }
        
        // 重新设置主题预览组件，确保图标颜色正确
        view?.post {
            setupThemePreviews()
        }
        
        // 显示主题切换成功提示
        Toast.makeText(requireContext(), "主题已切换为: ${theme.displayName}", Toast.LENGTH_SHORT).show()
        
        // 保存到数据库并记录日志
        lifecycleScope.launch(Dispatchers.IO) {
            try {
                ThemeManager.saveThemeToDatabase(requireContext(), theme)
                
                // 记录主题切换日志
                requireContext().logThemeChange(
                    scope = lifecycleScope,
                    oldTheme = oldTheme.displayName,
                    newTheme = theme.displayName
                )
            } catch (e: Exception) {
                // 忽略数据库保存错误
            }
        }
    }
    
    /**
     * 更新当前主题显示
     */
    private fun updateCurrentThemeDisplay() {
        val currentTheme = ThemeManager.getCurrentTheme(requireContext())
        currentThemeText.text = "当前主题: ${currentTheme.displayName}"
        
        // 更新主题卡片的选中状态视觉效果
        updateThemeCardSelection(currentTheme)
    }
    
    /**
     * 更新主题预览组件的选中状态
     */
    private fun updateThemeCardSelection(currentTheme: ThemeManager.Theme) {
        // 重置所有预览组件的样式
        resetThemeCardStyle(chinaRedPreview)
        resetThemeCardStyle(vibrantOrangePreview)
        resetThemeCardStyle(techBluePreview)
        
        // 高亮选中的主题预览组件
        when (currentTheme) {
            ThemeManager.Theme.CHINA_RED -> {
                setSelectedThemeCardStyle(chinaRedPreview, ThemeManager.Theme.CHINA_RED)
            }
            ThemeManager.Theme.VIBRANT_ORANGE -> {
                setSelectedThemeCardStyle(vibrantOrangePreview, ThemeManager.Theme.VIBRANT_ORANGE)
            }
            ThemeManager.Theme.TECH_BLUE -> {
                setSelectedThemeCardStyle(techBluePreview, ThemeManager.Theme.TECH_BLUE)
            }
        }
    }
    
    /**
     * 重置主题卡片样式
     */
    private fun resetThemeCardStyle(card: ThemePreviewComponent) {
        card.cardElevation = 8f
        card.alpha = 1.0f
        card.scaleX = 1.0f
        card.scaleY = 1.0f
        
        // 移除边框效果
        card.background = null
    }
    
    /**
     * 设置选中主题卡片样式
     */
    private fun setSelectedThemeCardStyle(card: ThemePreviewComponent, theme: ThemeManager.Theme) {
        card.cardElevation = 12f
        card.alpha = 1.0f
        card.scaleX = 1.0f
        card.scaleY = 1.0f
        
        // 添加简单的主题色边框
        val borderDrawable = android.graphics.drawable.GradientDrawable()
        borderDrawable.setStroke(4, getThemeStrokeColor(theme))
        borderDrawable.cornerRadius = 16f
        borderDrawable.setColor(android.graphics.Color.TRANSPARENT)
        
        card.background = borderDrawable
    }
    
    /**
     * 获取主题边框颜色
     */
    private fun getThemeStrokeColor(theme: ThemeManager.Theme): Int {
        return when (theme) {
            ThemeManager.Theme.CHINA_RED -> androidx.core.content.ContextCompat.getColor(requireContext(),
                cn.harry.cabinet.theme.constants.ThemeConstants.ChinaRedColors.primaryColorRes)
            ThemeManager.Theme.VIBRANT_ORANGE -> androidx.core.content.ContextCompat.getColor(requireContext(),
                cn.harry.cabinet.theme.constants.ThemeConstants.VibrantOrangeColors.primaryColorRes)
            ThemeManager.Theme.TECH_BLUE -> androidx.core.content.ContextCompat.getColor(requireContext(),
                cn.harry.cabinet.theme.constants.ThemeConstants.TechBlueColors.primaryColorRes)
        }
    }
}

